package com.example.file_study.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.file_study.constant.FileConstant;
import com.example.file_study.model.Result;
import com.example.file_study.service.FileMangerService;
import com.example.file_study.utils.FileZipCompressUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.zip.ZipFile;

@Service
@Slf4j
public class FilerMangerServiceImpl implements FileMangerService {


    @Override
    public void unzipPress(String zipPath, String desDir) {


            FileZipCompressUtils.unZippress(zipPath,desDir);



    }

    @Override
    public void downLoad(String path, HttpServletResponse response) throws IOException {


        //先分隔文件
        String[] arry = path.split(FileConstant.SPLIT_TAG);


        File tempFile = new File(FileConstant.ROOT_PATH + path);
        downLoadOne(response, tempFile);


    }


    @Override
    public void press(String paths, HttpServletResponse response) throws IOException, ExecutionException, InterruptedException {


        try {
            String compressFiles = FileZipCompressUtils.compressToDirs(Collections.singletonList(paths), "pressDemo");
            ZipFile zipFile = new ZipFile(compressFiles);

            if (zipFile.size() == 0) {
                response.setHeader("res", Base64.encodeBase64String(JSON.toJSONString(Result.fail("该文件夹没有文件。")).getBytes(StandardCharsets.UTF_8)));
                return;
            }
            File tempFile = new File(compressFiles);
            downLoadOne(response, tempFile);

        } catch (Exception e) {
            log.error("文件压缩错误");
        } finally {

        }


    }


    private void downLoadOne(HttpServletResponse response, File tempFile) throws IOException {

        InputStream inputStream = null;

        String tempFileName = null;
        ServletOutputStream outputStream = response.getOutputStream();

        try {


            if (!tempFile.exists()) {
                response.setHeader("res", Base64.encodeBase64String(JSON.toJSONString(Result.fail("文件不存在")).getBytes(StandardCharsets.UTF_8)));
                log.error("{}=>文件不存在！", tempFile.toPath());
                return;
            }

            tempFileName = tempFile.getName();
            log.info("最后拿到的 path=>{}: name=>{}", tempFile.toPath(), tempFileName);


            setFileHeader(tempFileName, response);

            inputStream = Files.newInputStream(tempFile.toPath());
            byte[] buff = new byte[2048];
            int len = 0;
            while ((len = inputStream.read(buff)) > 0) {
                outputStream.write(buff, 0, len);
                outputStream.flush();
            }
            outputStream.write(buff);
            outputStream.flush();
            outputStream.close();

        } catch (Exception e) {
            log.error("单文件下载出错!");
        } finally {
            inputStream.close();
            //删除 临时文件
            tempFile.delete();
        }


    }


    private void setFileHeader(String finame, HttpServletResponse response) throws UnsupportedEncodingException {
        // 清空response
        response.reset();
        // 设置response的Header
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/octet-stream;charset=utf-8");
        //     response.addHeader("Content-Disposition", "attachment;fileName=" + Base64.encodeBase64String(tempFileName.getBytes(StandardCharsets.UTF_8)));
        //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
        //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
        // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(finame, "UTF-8"));

    }
}
